package mgodb

import (
	"github.com/facebookgo/inject"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"github.com/pkg/errors"
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/service/mongo"
	"time"
)

// cPublicResource 公共资源管理数据表
const cPublicResource = "oper_public_resource"

// ResourceManagement 公共资源管理
type ResourceManagement struct {
	DB *mongo.DB
}

// Init 初始化
func (a *ResourceManagement) Init(g *inject.Graph, db *mongo.DB) {
	a.DB = db

	// 初始化mongo索引
	a.DB.C(cPublicResource, func(c *mgo.Collection) error {
		c.EnsureIndex(mgo.Index{
			Key:    []string{"record_id", "deleted"},
			Unique: true,
		})
		c.EnsureIndexKey("_id")
		return nil
	})

	var val model.IResourceManagement = a
	g.Provide(&inject.Object{Value: val, Name: "IResourceManagement"})
}

// QueryPage 查询分页
func (a *ResourceManagement) QueryPage(param *schema.RMQParams, pageIndex, pageSize uint) (int, []*schema.ResourceManagement, error) {
	query := bson.M{
		"deleted": 0,
	}
	//	添加查询资源名称
	if param.RName != "" {
		query["resource_name"] = bson.M{"$regex": param.RName}
	}
	//	添加查询资源分类
	if param.ClassID != "" {
		query["classification_id"] = param.ClassID
	}
	//	添加查询地址
	if param.Address != "" {
		query["address"] = bson.M{"$regex": param.Address}
	}
	//	添加查询状态
	if param.Status != 0 {
		query["available_status"] = param.Status
	}
	var n int
	var items []*schema.ResourceManagement
	var err error
	err = a.DB.C(cPublicResource, func(c *mgo.Collection) error {
		n, err = c.Find(query).Count()
		if err != nil {
			return err
		}
		if n == 0 {
			return nil
		}
		return c.Find(query).Sort("-created").Skip(int((pageIndex - 1) * pageSize)).Limit(int(pageSize)).All(&items)
	})
	if err != nil {
		return 0, nil, errors.Wrapf(err, "查询分页数据发生错误")
	}

	return n, items, nil
}

// Create 创建资源
func (a *ResourceManagement) Create(item *schema.ResourceManagement) error {
	err := a.DB.C(cPublicResource, func(c *mgo.Collection) error {
		id, err := a.DB.IncrID(cPublicResource)
		if err != nil {
			return err
		}
		item.ID = id
		return c.Insert(item)
	})
	if err != nil {
		return errors.Wrapf(err, "创建数据发生错误")
	}
	return nil
}

// Get 查询资源
func (a *ResourceManagement) Get(param string) (*schema.ResourceManagement, error) {
	item := new(schema.ResourceManagement)
	err := a.DB.C(cPublicResource, func(c *mgo.Collection) error {
		return c.Find(bson.M{"record_id": param}).One(item)
	})
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, errors.Wrapf(err, "精确查询数据发生错误")
	}
	return item, nil
}

// Update 更新资源
func (a *ResourceManagement) Update(id string, itemMap map[string]interface{}) error {
	err := a.DB.C(cPublicResource, func(c *mgo.Collection) error {
		return c.Update(bson.M{"record_id": id}, bson.M{"$set": itemMap})
	})
	if err != nil {
		return errors.Wrapf(err, "更新数据发生错误")
	}
	return nil
}

// Delete 标记删除资源
func (a *ResourceManagement) Delete(param string) error {
	info := map[string]interface{}{
		"deleted": time.Now().Unix(),
	}
	err := a.DB.C(cPublicResource, func(c *mgo.Collection) error {
		return c.Update(bson.M{"record_id": param}, bson.M{"$set": info})
	})
	if err != nil {
		return errors.Wrapf(err, "删除数据发生错误")
	}
	return nil
}

func (a *ResourceManagement) QueryAvailableRes() ([]*schema.ResourceManagement, error) {
	query := bson.M{
		"deleted":          0,
		"available_status": 1,
	}
	var items []*schema.ResourceManagement
	var err error
	err = a.DB.C(cPublicResource, func(c *mgo.Collection) error {
		return c.Find(query).Limit(100).All(&items) //	默认查询100条以内
	})
	if err != nil {
		return nil, errors.Wrapf(err, "查询可用资源发生错误")
	}
	return items, nil
}
